package game.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import common.config.exception.CustomException;
import common.mapper.CommonGItemMapper;
import common.model.enums.RecipeProductTypeEnum;
import common.model.po.GClassification;
import common.model.po.GItem;
import common.model.po.GRecipeItem;
import common.model.request.base.PaginationRequest;
import common.model.response.base.Result;
import common.service.CommonGRecipeItemService;
import game.mapper.GItemMapper;
import game.model.converter.GItemConverter;
import game.model.request.SaveItemRequest;
import game.model.request.SearchItemRequest;
import game.model.vo.ItemDetailVo;
import game.model.vo.SearchItemVo;
import game.service.GClassificationService;
import game.service.GItemService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 物品（包括零件和设备两类）服务实现类
 *
 * @author 米泽鹏
 * @since 2022-02-26
 */
@Slf4j
@Service
public class GItemServiceImpl extends ServiceImpl<CommonGItemMapper, GItem> implements GItemService {

	@Resource
	private GItemMapper mapper;
	@Resource
	private CommonGRecipeItemService recipeItemService;
	@Resource
	private GClassificationService classificationService;


	@Override
	public Page<SearchItemVo> searchItemByPage(PaginationRequest<SearchItemRequest, GItem> paginationRequest) {
		return mapper.pageSearchItem(paginationRequest.buildPage(), paginationRequest.getParams());
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public Result<?> saveItem(SaveItemRequest request) {
		GItem gItem = GItemConverter.saveRequestToPo(request);
		if (gItem.getId() == null) {
			save(gItem);
		} else {
			// 物品名称修改后需要连带修改g_recipe_item表的item_name字段
			GItem gItemOriginal = getById(gItem.getId());
			if (!gItemOriginal.getItemName().equals(gItem.getItemName())) {
				recipeItemService.lambdaUpdate().eq(GRecipeItem::getType, 0).eq(GRecipeItem::getItemId, gItem.getId()).or().eq(GRecipeItem::getType, 1).eq(GRecipeItem::getProductType, 1).eq(GRecipeItem::getItemId, gItem.getId()).set(GRecipeItem::getItemName, gItem.getItemName()).update();
			}
			updateById(gItem);
		}
		return Result.success();
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public Result<?> deleteItem(Long id) {
		// 检查是否有配方占用此物品
		List<GRecipeItem> recipeItemList = recipeItemService.lambdaQuery().eq(GRecipeItem::getItemId, id).eq(GRecipeItem::getProductType, RecipeProductTypeEnum.ITEM.getValue()).list();
		Set<Long> recipeIdSet = recipeItemList.stream().map(GRecipeItem::getRecipeId).collect(Collectors.toSet());
		if (!recipeIdSet.isEmpty()) {
			throw new CustomException("有" + recipeIdSet.size() + "个配方正在使用此物品，无法删除");
		}
		// 删除物品
		removeById(id);
		return Result.success();
	}

	@Override
	public ItemDetailVo getItemDetailById(Long itemId) {
		GItem item = getById(itemId);
		ItemDetailVo itemDetailVo = GItemConverter.poToItemDetailVo(item);
		// 全类别
		GClassification classification;
		Long classificationId = item.getClassificationId();
		do {
			classification = classificationService.getById(classificationId);
			if (classification != null) {
				itemDetailVo.getClassificationNameList().add(classification.getName());
				classificationId = classification.getParentId();
			}
		} while (classification != null && classificationId != 0);
		Collections.reverse(itemDetailVo.getClassificationNameList());
		return itemDetailVo;
	}

}
